package com.yikome.uaa.service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.criteria.Predicate;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.yikome.common.CommonService;
import com.yikome.uaa.domain.Authority;
import com.yikome.uaa.repository.AuthorityRepository;
import com.yikome.uaa.utils.UserAuthoritiesUtils;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;

@Service
public class AuthorityService extends CommonService<Authority, Long>{

	@Autowired
	private AuthorityRepository authorityRepository ; 
	
	@Autowired
	private NamedParameterJdbcTemplate jdbcTemplate; 
	
	@Autowired
	public void setResourceDao(AuthorityRepository repository) {
		super.setCommonDao(repository);
	}

	public List<Authority> findAllAuthority() {
		
		List<Authority> authorities = authorityRepository.findAll((root,query,cb) -> {
			List<Predicate> predicates = new ArrayList<>();
			predicates.add(cb.equal(root.get("yn"),1));
			return cb.and(predicates.toArray(new Predicate[predicates.size()]));
		});
		
		Set<Authority> userMenu = new HashSet<Authority>(authorities);
		
		Set<Authority> collectionUserAuthority = UserAuthoritiesUtils.collectionUserAuthority(userMenu);
		
		return new ArrayList<>(collectionUserAuthority);
	}

	@Transactional
	public Authority saveUpdateAuthority(Authority authority) {
		
		if(authority.getId() != null) {
			Authority target = authorityRepository.findById(authority.getId()).orElse(null);
			Preconditions.checkArgument(target != null , "数据对象不存在....");
			BeanUtils.copyProperties(authority, target);
			return authorityRepository.save(target);
		}
		return authorityRepository.save(authority);
	}

	@Transactional
	public Boolean deleteAuthority(Long authorityId) {
		Authority target = authorityRepository.findById(authorityId).orElse(null);
		Preconditions.checkArgument(target != null , "数据对象不存在....");
		
		List<Long> deleteAuthorityIds = new ArrayList<>(); 
		deleteAuthorityIds.add(authorityId);
		if(target.getType() == 1) {
			Long childrenSizes = jdbcTemplate.queryForObject("SELECT COUNT(1) FROM u_authority WHERE u_authority.parent_id = :authorityId", ImmutableMap.of("authorityId", authorityId), Long.class);
			if(childrenSizes > 0) {
				String sql ="SELECT u_authority.id FROM u_authority WHERE u_authority.parent_id = :authorityId \n" + 
							"UNION \n" + 
							"SELECT \n" + 
							" u_authority.id \n" + 
							"FROM  \n" + 
							"(SELECT * FROM u_authority WHERE u_authority.parent_id = :authorityId) vo LEFT JOIN u_authority ON (vo.id = u_authority.parent_id)";
				deleteAuthorityIds.addAll(jdbcTemplate.queryForList(sql, ImmutableMap.of("authorityId", authorityId), Long.class));
			}
		}else if(target.getType() == 2) {
			Long childrenSizes = jdbcTemplate.queryForObject("SELECT COUNT(1) FROM u_authority WHERE u_authority.parent_id = :authorityId", ImmutableMap.of("authorityId", authorityId), Long.class);
			if(childrenSizes > 0) {
				deleteAuthorityIds.addAll(jdbcTemplate.queryForList("SELECT u_authority.id FROM u_authority WHERE u_authority.parent_id = :authorityId", ImmutableMap.of("authorityId", authorityId), Long.class));
			}
		}
		jdbcTemplate.update("DELETE FROM u_role_authority WHERE u_role_authority.authority_id IN (:authorityIds)", ImmutableMap.of("authorityIds", deleteAuthorityIds));
		jdbcTemplate.update("DELETE FROM u_authority WHERE u_authority.id IN (:authorityIds)", ImmutableMap.of("authorityIds", deleteAuthorityIds));
		return true ;
	}
}
